# -*- coding: utf-8 -*-
#
from .helpers import _s3, _s21, _s111

from ..helpers import untangle


class WitherdenVincent(object):
    '''
    F.D. Witherden, P.E. Vincent,
    On the identification of symmetric quadrature rules for finite
    element methods,
    Computers & Mathematics with Applications,
    Volume 69, Issue 10, May 2015, Pages 1232–1241,
    <https://doi.org/10.1016/j.camwa.2015.03.017>.

    Abstract:
    In this paper we describe a methodology for the identification of symmetric
    quadrature rules inside of quadrilaterals, triangles, tetrahedra, prisms,
    pyramids, and hexahedra. The methodology is free from manual intervention
    and is capable of identifying a set of rules with a given strength and a
    given number of points. We also present polyquad which is an implementation
    of our methodology. Using polyquad v1.0 we proceed to derive a complete set
    of symmetric rules on the aforementioned domains. All rules possess purely
    positive weights and have all points inside the domain. Many of the rules
    appear to be new, and an improvement over those tabulated in the
    literature.
    '''
    def __init__(self, degree, symbolic=False):
        self.name = 'WV({})'.format(degree)
        self.degree = degree
        if degree == 1:
            data = [
                (1.000000000000000e+00, _s3(symbolic)),
                ]
        elif degree == 2:
            data = [
                (3.333333333333333e-01, _s21(1.666666666666667e-01)),
                ]
        elif degree == 4:
            data = [
                (2.233815896780115e-01, _s21(4.459484909159649e-01)),
                (1.099517436553219e-01, _s21(9.157621350977074e-02)),
                ]
        elif degree == 5:
            data = [
                (2.250000000000000e-01, _s3(symbolic)),
                (1.259391805448271e-01, _s21(1.012865073234563e-01)),
                (1.323941527885062e-01, _s21(4.701420641051151e-01)),
                ]
        elif degree == 6:
            data = [
                (5.084490637020682e-02, _s21(6.308901449150223e-02)),
                (1.167862757263794e-01, _s21(2.492867451709104e-01)),
                (8.285107561837357e-02, _s111(6.365024991213987e-01, 3.103524510337844e-01)),
                ]
        elif degree == 7:
            data = [
                (1.654505011079213e-02, _s21(3.373064855458785e-02)),
                (1.279441712301556e-01, _s21(2.415773825954036e-01)),
                (7.708664618598607e-02, _s21(4.743096925047182e-01)),
                (5.587873290319978e-02, _s111(7.542800405500532e-01, 1.986833147973517e-01)),
                ]
        elif degree == 8:
            data = [
                (1.443156076777872e-01, _s3(symbolic)),
                (9.509163426728462e-02, _s21(4.592925882927231e-01)),
                (1.032173705347182e-01, _s21(1.705693077517602e-01)),
                (3.245849762319808e-02, _s21(5.054722831703096e-02)),
                (2.723031417443499e-02, _s111(7.284923929554042e-01, 2.631128296346381e-01)),
                ]
        elif degree == 9:
            data = [
                (9.713579628279884e-02, _s3(symbolic)),
                (7.782754100477428e-02, _s21(4.370895914929366e-01)),
                (7.964773892721025e-02, _s21(1.882035356190327e-01)),
                (3.133470022713907e-02, _s21(4.896825191987376e-01)),
                (2.557767565869803e-02, _s21(4.472951339445269e-02)),
                (4.328353937728938e-02, _s111(7.411985987844980e-01, 2.219629891607657e-01)),
                ]
        elif degree == 10:
            data = [
                (8.174332914628597e-02, _s3(symbolic)),
                (1.335296881314957e-02, _s21(3.205537321694352e-02)),
                (4.595796360474473e-02, _s21(1.421611010565644e-01)),
                (6.390490639642404e-02, _s111(5.300541189273440e-01, 3.218129952888354e-01)),
                (3.418464816295943e-02, _s111(6.012333286834592e-01, 3.691467818278109e-01)),
                (2.529775770728838e-02, _s111(8.079306009228790e-01, 1.637017337371824e-01)),
                ]
        elif degree == 11:
            data = [
                (8.576117973222422e-02, _s3(symbolic)),
                (1.043187051289470e-02, _s21(2.848541761437190e-02)),
                (7.051568411171658e-02, _s21(2.102199567031783e-01)),
                (3.863075923701932e-02, _s21(1.026354827122464e-01)),
                (1.660627305458537e-02, _s21(4.958919009658909e-01)),
                (6.731615407946830e-02, _s21(4.384659267643522e-01)),
                (1.029028957295328e-02, _s111(8.433497836618531e-01, 1.493247886520824e-01)),
                (4.033247664050055e-02, _s111(6.644083741968642e-01, 2.895811256377059e-01)),
                ]
        elif degree == 12:
            data = [
                (2.426683808145203e-02, _s21(4.882037509455415e-01)),
                (2.848605206887754e-02, _s21(1.092578276593543e-01)),
                (6.254121319590276e-02, _s21(2.714625070149261e-01)),
                (7.931642509973639e-03, _s21(2.464636343633558e-02)),
                (4.991833492806094e-02, _s21(4.401116486585931e-01)),
                (2.178358503860756e-02, _s111(6.853101639063919e-01, 2.916556797383409e-01)),
                (4.322736365941421e-02, _s111(6.282497516835561e-01, 2.554542286385173e-01)),
                (1.508367757651144e-02, _s111(8.513377925102401e-01, 1.272797172335894e-01)),
                ]
        elif degree == 13:
            data = [
                (6.796003658683164e-02, _s3(symbolic)),
                (2.399440192889473e-02, _s21(4.890769464525394e-01)),
                (5.827848511919998e-02, _s21(2.213722862918329e-01)),
                (5.560196753045333e-02, _s21(4.269414142598004e-01)),
                (6.052337103539172e-03, _s21(2.150968110884316e-02)),
                (2.417903981159382e-02, _s111(7.485071158999522e-01, 1.635974010678505e-01)),
                (1.496540110516567e-02, _s111(8.647077702954428e-01, 1.109220428034634e-01)),
                (3.464127614084837e-02, _s111(6.235459955536755e-01, 3.084417608921178e-01)),
                (9.590681003543263e-03, _s111(7.223577931241880e-01, 2.725158177734296e-01)),
                ]
        elif degree == 14:
            data = [
                (4.216258873699302e-02, _s21(1.772055324125434e-01)),
                (3.278835354412535e-02, _s21(4.176447193404539e-01)),
                (1.443369966977667e-02, _s21(6.179988309087259e-02)),
                (2.188358136942889e-02, _s21(4.889639103621786e-01)),
                (5.177410450729159e-02, _s21(2.734775283088386e-01)),
                (4.923403602400082e-03, _s21(1.939096124870104e-02)),
                (1.443630811353384e-02, _s111(6.869801678080878e-01, 2.983728821362578e-01)),
                (2.466575321256367e-02, _s111(7.706085547749965e-01, 1.722666878213557e-01)),
                (3.857151078706068e-02, _s111(5.702222908466832e-01, 3.368614597963450e-01)),
                (5.010228838500672e-03, _s111(8.797571713701711e-01, 1.189744976969569e-01)),
                ]
        elif degree == 15:
            data = [
                (4.433538738218407e-02, _s3(symbolic)),
                (4.271378157146057e-02, _s21(4.053622141339755e-01)),
                (1.644473756262516e-02, _s21(7.017355289998600e-02)),
                (1.739614800076341e-02, _s21(4.741706814380198e-01)),
                (4.678336172870963e-02, _s21(2.263787134203496e-01)),
                (9.573846182460086e-03, _s21(4.949969567691262e-01)),
                (2.960774637905375e-03, _s21(1.581172625098864e-02)),
                (1.560257283057596e-02, _s111(6.669756448018681e-01, 3.146482428124509e-01)),
                (4.029853372018099e-03, _s111(9.199121577262361e-01, 7.094860523645541e-02)),
                (2.872058692520134e-02, _s111(7.152223569314506e-01, 1.905355894763939e-01)),
                (1.167262118157585e-02, _s111(8.132926410494192e-01, 1.680686452224144e-01)),
                (3.131547628496929e-02, _s111(5.652526648771142e-01, 3.389506114752772e-01)),
                ]
        elif degree == 16:
            data = [
                (4.526456607381879e-02, _s3(symbolic)),
                (4.109292314369895e-02, _s21(2.459900704671417e-01)),
                (4.071183331242536e-02, _s21(4.155848968854205e-01)),
                (1.478163469022440e-02, _s21(8.535556658670035e-02)),
                (2.941840969898810e-02, _s21(1.619186441912712e-01)),
                (4.418546312150569e-03, _s21(5.000000000000000e-01)),
                (2.597433329827716e-02, _s21(4.752807275459421e-01)),
                (1.893827246441570e-02, _s111(7.541700614447677e-01, 1.910747636405292e-01)),
                (1.654466714835048e-03, _s111(9.682443680309587e-01, 2.320342776881373e-02)),
                (1.500860178428581e-02, _s111(6.493036982454464e-01, 3.317645234741476e-01)),
                (7.947593933392498e-03, _s111(9.002737032704295e-01, 8.069616698587301e-02)),
                (3.198361007937007e-02, _s111(5.891488405642479e-01, 3.082449691963540e-01)),
                (5.391187116848811e-03, _s111(8.066218674993957e-01, 1.874417824837821e-01)),
                ]
        elif degree == 17:
            data = [
                (2.731092652810211e-02, _s21(4.171034443615992e-01)),
                (2.773887577637642e-03, _s21(1.475549166075396e-02)),
                (2.501945095049736e-02, _s21(4.655978716188903e-01)),
                (2.631263058801799e-02, _s21(1.803581162663706e-01)),
                (1.245900080230544e-02, _s21(6.665406347959690e-02)),
                (3.771623715279528e-02, _s21(2.857065024365866e-01)),
                (7.978300205929593e-03, _s111(8.247900701650881e-01, 1.591922874727927e-01)),
                (2.248777254669107e-02, _s111(6.263690303864522e-01, 3.062815917461865e-01)),
                (1.039843995583954e-02, _s111(5.712948679446841e-01, 4.154754592952290e-01)),
                (2.055789832045452e-02, _s111(7.532351459364581e-01, 1.687225134952595e-01)),
                (8.692214501001192e-03, _s111(7.150722591106424e-01, 2.717918700553549e-01)),
                (4.584348401735867e-03, _s111(9.159193532978169e-01, 7.250547079900249e-02)),
                (2.617162593533699e-02, _s111(5.432755795961598e-01, 2.992189424769702e-01)),
                ]
        elif degree == 18:
            data = [
                (3.635573530142667e-02, _s3(symbolic)),
                (3.330447003339013e-02, _s21(3.999556280675762e-01)),
                (1.204664763399971e-02, _s21(4.875803015748695e-01)),
                (1.894917150677887e-02, _s21(4.618095064064492e-01)),
                (3.647508940894364e-02, _s21(2.422647025142720e-01)),
                (7.129326019718970e-03, _s21(3.883025608868562e-02)),
                (1.655915995200325e-02, _s21(9.194774212164319e-02)),
                (1.375961623494221e-02, _s111(7.703723762146752e-01, 1.838227079254640e-01)),
                (2.378191090015283e-02, _s111(6.709539851942345e-01, 2.063492574338379e-01)),
                (4.530534502257065e-03, _s111(6.004189546342569e-01, 3.956834343322697e-01)),
                (6.840110119607182e-03, _s111(8.783421894675217e-01, 1.081957937910333e-01)),
                (1.774748910202040e-02, _s111(6.399880920047146e-01, 3.197516245253773e-01)),
                (5.010660874579722e-03, _s111(7.589294798551984e-01, 2.357721849581917e-01)),
                (1.222948126961090e-03, _s111(9.723607289627957e-01, 2.709091099516203e-02)),
                (2.548217531182444e-02, _s111(5.459187753861946e-01, 3.334935294498808e-01)),
                ]
        elif degree == 19:
            data = [
                (3.446939770401233e-02, _s3(symbolic)),
                (7.109256597798131e-03, _s21(5.252389035120897e-02)),
                (1.032175514294428e-02, _s21(4.925126750413369e-01)),
                (1.523435109301830e-02, _s21(1.114488733230214e-01)),
                (2.298359002674161e-02, _s21(4.591942010395437e-01)),
                (3.153753489315497e-02, _s21(4.039697225519012e-01)),
                (2.465191484819085e-02, _s21(1.781701047817643e-01)),
                (1.765322776442848e-03, _s21(1.163946118378945e-02)),
                (3.175301936600308e-02, _s21(2.551616329136077e-01)),
                (9.695484486855047e-03, _s111(8.301564644002754e-01, 1.306976762680324e-01)),
                (2.634632197739073e-02, _s111(5.593698057203009e-01, 3.113176298095413e-01)),
                (3.282076551835819e-03, _s111(6.333132931287841e-01, 3.646177809746111e-01)),
                (1.810794493121245e-02, _s111(7.040048199660421e-01, 2.214348854323311e-01)),
                (2.926315103470200e-03, _s111(8.525669543768892e-01, 1.424257573657564e-01)),
                (1.610216276402411e-02, _s111(6.050839790687079e-01, 3.540280097352753e-01)),
                (8.455887499536496e-03, _s111(7.431813689574364e-01, 2.418945789605796e-01)),
                (3.327201362859388e-03, _s111(9.301376988768051e-01, 6.008627532230670e-02)),
                ]
        else:
            assert degree == 20
            data = [
                (2.782022140290623e-02, _s3(symbolic)),
                (2.816640261504049e-02, _s21(2.545792676733391e-01)),
                (1.597681582133240e-03, _s21(1.097614102839778e-02)),
                (1.566046155214907e-02, _s21(1.093835967117146e-01)),
                (1.834692594850583e-02, _s21(1.862949977445409e-01)),
                (1.890479986646490e-02, _s21(4.455510569559248e-01)),
                (4.322550821331155e-03, _s21(3.731088059888471e-02)),
                (2.757610125814092e-02, _s21(3.934253478170999e-01)),
                (1.420365060681688e-02, _s21(4.762456115404990e-01)),
                (4.405794837116995e-03, _s111(8.332955118382362e-01, 1.591337076570672e-01)),
                (1.197279715790938e-02, _s111(7.549215028635474e-01, 1.985181322287883e-01)),
                (2.259739204251731e-03, _s111(9.310544767839422e-01, 6.409058560843406e-02)),
                (1.733445113443867e-02, _s111(6.118777035474257e-01, 3.331348173095876e-01)),
                (8.291423055227716e-03, _s111(8.616840189364867e-01, 9.995229628813868e-02)),
                (1.544521564419846e-02, _s111(6.781657378896355e-01, 2.156070573900944e-01)),
                (7.391363000510596e-03, _s111(5.701446928909734e-01, 4.200237588162241e-01)),
                (2.338349146365547e-02, _s111(5.423318041724281e-01, 3.178601238357720e-01)),
                (7.156400476915370e-03, _s111(7.086813757203236e-01, 2.805814114236653e-01)),
                ]

        self.bary, self.weights = untangle(data)
        self.points = self.bary[:, 1:]
        return
